package com.bwie.shopcar.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
import com.bwie.common.constants.TokenConstants;
import com.bwie.common.domain.Coupon;
import com.bwie.common.domain.ShopCar;
import com.bwie.common.domain.Systems;
import com.bwie.common.domain.User;
import com.bwie.common.domain.request.ShopRequset;
import com.bwie.common.result.Result;
import com.bwie.common.utils.JwtUtils;
import com.bwie.shopcar.service.ShopCarService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/shop")
public class ShopCarController {
    @Autowired
    private ShopCarService service;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 购物车列表
     * @return
     */
    @GetMapping("showCars")
    public Result showCars(){
        List<ShopRequset> list = service.showCars();
        return Result.success(list);
    }

    /**
     * 购物车内商品数量可以进行编辑，最小为1
     * @param shopCar
     * @return
     */
    @PostMapping("updateAmount")
    public Result updateAmount(@RequestBody ShopCar shopCar){
        Integer shopcarAmount = shopCar.getShopcarAmount();
        if (shopcarAmount >= 1) {
            Integer upd = service.updateAmount(shopCar.getShopcarAmount(),shopCar.getShopcarId());
        }else{
            return Result.error("商品数量最小为1");
        }
        return Result.success(shopCar);
    }

    /**
     * 优惠券下拉框
     * @return
     */
    @GetMapping("downPacket")
    public Result downPacket(){
        //获取登录用户
        String token = request.getHeader("token");
        String userKey = JwtUtils.getUserKey(token);
        String userKey1 = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        User user = JSONObject.parseObject(userKey1, User.class);
        List<Coupon> down = service.downPacket(user.getUserId());
        return Result.success(down);
    }

    /**
     * 移除购物车
     * @param shopcarId
     * @return
     */
    @PostMapping("/deleteShop/{shopcarId}")
    public Result deleteShop(@PathVariable Integer shopcarId){
        Integer delete = service.deleteShop(shopcarId);
        return delete>0?Result.success(shopcarId):Result.error("删除成功");
    }


    /**
     * 购买购物车里的商品
     * @param shopcarId
     * @return
     */
    @PostMapping("/buyProduct/{shopcarId}")
    public Result buyProduct(@PathVariable Integer shopcarId){
        Integer buy = service.buyProduct(shopcarId);
        if (buy > 0) {
            //获取登录用户
            String token = request.getHeader("token");
            String userKey = JwtUtils.getUserKey(token);
            String userKey1 = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
            User user = JSONObject.parseObject(userKey1, User.class);
            //获取购买的信息
            List<ShopCar> find = service.findId(shopcarId);
            for (ShopCar shopCar : find) {
                Integer shopcarPrice = shopCar.getShopcarPrice();
                int i = user.getUserMoney() - shopCar.getShopcarPrice();
                user.setUserMoney(i);
                service.updateMoney(user.getUserMoney(),user.getUserId());
                if (shopcarPrice < 88) {
                    return Result.error("购物消费满88元可以参与活动");
                }
            }
            //购物完成给优惠券系统发送消息
            Systems systems = new Systems();
            systems.setSystemMessage("购买成功");
            service.addSystems(systems);
        }
        return buy>0?Result.success(shopcarId):Result.error("购买失败");
    }

    /**
     *优惠券系统接收到消息之后，查询当前可派发优惠券进行随机派发，派发一个优惠券优惠券数量减一
     * @param coupon
     * @return
     */
    @PostMapping("giveUserCoupon")
    public Result giveUserCoupon(@RequestBody Coupon coupon){
        //商品优惠券发放过程中需要使用redisson加锁保证，优惠券不会超出数量
        RLock lock = redissonClient.getLock("aa");
        try {
            boolean tryLock = lock.tryLock(100, 30, TimeUnit.SECONDS);
            Integer give=service.giveUserCoupon(coupon);
            if (give > 0) {
                //MQ发送消息必须不可重复、不可丢失
                rabbitTemplate.convertAndSend("sendMessagee",coupon,message -> {
                    message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
                    return message;
                });
            }
            if (tryLock) {
               return Result.error("请等待其他操作完成");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //释放锁
        finally {
            lock.unlock();
        }
        return Result.success("发送优惠券成功");
    }

}
